/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Control;

import Control.exceptions.IllegalOrphanException;
import Control.exceptions.NonexistentEntityException;
import Control.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entidades.Tarjeta;
import Entidades.Factura;
import Entidades.Efectivo;
import Entidades.Cheque;
import Entidades.Pago;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author USUARIO
 */
public class PagoJpaController implements Serializable {

    public PagoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Pago pago) throws PreexistingEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Tarjeta tarjeta = pago.getTarjeta();
            if (tarjeta != null) {
                tarjeta = em.getReference(tarjeta.getClass(), tarjeta.getNroTransaccion());
                pago.setTarjeta(tarjeta);
            }
            Factura factura = pago.getFactura();
            if (factura != null) {
                factura = em.getReference(factura.getClass(), factura.getNroFactura());
                pago.setFactura(factura);
            }
            Efectivo efectivo = pago.getEfectivo();
            if (efectivo != null) {
                efectivo = em.getReference(efectivo.getClass(), efectivo.getNroTransaccion());
                pago.setEfectivo(efectivo);
            }
            Cheque cheque = pago.getCheque();
            if (cheque != null) {
                cheque = em.getReference(cheque.getClass(), cheque.getNroTransaccion());
                pago.setCheque(cheque);
            }
            em.persist(pago);
            if (tarjeta != null) {
                Pago oldPagoOfTarjeta = tarjeta.getPago();
                if (oldPagoOfTarjeta != null) {
                    oldPagoOfTarjeta.setTarjeta(null);
                    oldPagoOfTarjeta = em.merge(oldPagoOfTarjeta);
                }
                tarjeta.setPago(pago);
                tarjeta = em.merge(tarjeta);
            }
            if (factura != null) {
                factura.getPagoList().add(pago);
                factura = em.merge(factura);
            }
            if (efectivo != null) {
                Pago oldPagoOfEfectivo = efectivo.getPago();
                if (oldPagoOfEfectivo != null) {
                    oldPagoOfEfectivo.setEfectivo(null);
                    oldPagoOfEfectivo = em.merge(oldPagoOfEfectivo);
                }
                efectivo.setPago(pago);
                efectivo = em.merge(efectivo);
            }
            if (cheque != null) {
                Pago oldPagoOfCheque = cheque.getPago();
                if (oldPagoOfCheque != null) {
                    oldPagoOfCheque.setCheque(null);
                    oldPagoOfCheque = em.merge(oldPagoOfCheque);
                }
                cheque.setPago(pago);
                cheque = em.merge(cheque);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findPago(pago.getNroTransaccion()) != null) {
                throw new PreexistingEntityException("Pago " + pago + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Pago pago) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Pago persistentPago = em.find(Pago.class, pago.getNroTransaccion());
            Tarjeta tarjetaOld = persistentPago.getTarjeta();
            Tarjeta tarjetaNew = pago.getTarjeta();
            Factura facturaOld = persistentPago.getFactura();
            Factura facturaNew = pago.getFactura();
            Efectivo efectivoOld = persistentPago.getEfectivo();
            Efectivo efectivoNew = pago.getEfectivo();
            Cheque chequeOld = persistentPago.getCheque();
            Cheque chequeNew = pago.getCheque();
            List<String> illegalOrphanMessages = null;
            if (tarjetaOld != null && !tarjetaOld.equals(tarjetaNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Tarjeta " + tarjetaOld + " since its pago field is not nullable.");
            }
            if (efectivoOld != null && !efectivoOld.equals(efectivoNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Efectivo " + efectivoOld + " since its pago field is not nullable.");
            }
            if (chequeOld != null && !chequeOld.equals(chequeNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Cheque " + chequeOld + " since its pago field is not nullable.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (tarjetaNew != null) {
                tarjetaNew = em.getReference(tarjetaNew.getClass(), tarjetaNew.getNroTransaccion());
                pago.setTarjeta(tarjetaNew);
            }
            if (facturaNew != null) {
                facturaNew = em.getReference(facturaNew.getClass(), facturaNew.getNroFactura());
                pago.setFactura(facturaNew);
            }
            if (efectivoNew != null) {
                efectivoNew = em.getReference(efectivoNew.getClass(), efectivoNew.getNroTransaccion());
                pago.setEfectivo(efectivoNew);
            }
            if (chequeNew != null) {
                chequeNew = em.getReference(chequeNew.getClass(), chequeNew.getNroTransaccion());
                pago.setCheque(chequeNew);
            }
            pago = em.merge(pago);
            if (tarjetaNew != null && !tarjetaNew.equals(tarjetaOld)) {
                Pago oldPagoOfTarjeta = tarjetaNew.getPago();
                if (oldPagoOfTarjeta != null) {
                    oldPagoOfTarjeta.setTarjeta(null);
                    oldPagoOfTarjeta = em.merge(oldPagoOfTarjeta);
                }
                tarjetaNew.setPago(pago);
                tarjetaNew = em.merge(tarjetaNew);
            }
            if (facturaOld != null && !facturaOld.equals(facturaNew)) {
                facturaOld.getPagoList().remove(pago);
                facturaOld = em.merge(facturaOld);
            }
            if (facturaNew != null && !facturaNew.equals(facturaOld)) {
                facturaNew.getPagoList().add(pago);
                facturaNew = em.merge(facturaNew);
            }
            if (efectivoNew != null && !efectivoNew.equals(efectivoOld)) {
                Pago oldPagoOfEfectivo = efectivoNew.getPago();
                if (oldPagoOfEfectivo != null) {
                    oldPagoOfEfectivo.setEfectivo(null);
                    oldPagoOfEfectivo = em.merge(oldPagoOfEfectivo);
                }
                efectivoNew.setPago(pago);
                efectivoNew = em.merge(efectivoNew);
            }
            if (chequeNew != null && !chequeNew.equals(chequeOld)) {
                Pago oldPagoOfCheque = chequeNew.getPago();
                if (oldPagoOfCheque != null) {
                    oldPagoOfCheque.setCheque(null);
                    oldPagoOfCheque = em.merge(oldPagoOfCheque);
                }
                chequeNew.setPago(pago);
                chequeNew = em.merge(chequeNew);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = pago.getNroTransaccion();
                if (findPago(id) == null) {
                    throw new NonexistentEntityException("The pago with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Pago pago;
            try {
                pago = em.getReference(Pago.class, id);
                pago.getNroTransaccion();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The pago with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Tarjeta tarjetaOrphanCheck = pago.getTarjeta();
            if (tarjetaOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pago (" + pago + ") cannot be destroyed since the Tarjeta " + tarjetaOrphanCheck + " in its tarjeta field has a non-nullable pago field.");
            }
            Efectivo efectivoOrphanCheck = pago.getEfectivo();
            if (efectivoOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pago (" + pago + ") cannot be destroyed since the Efectivo " + efectivoOrphanCheck + " in its efectivo field has a non-nullable pago field.");
            }
            Cheque chequeOrphanCheck = pago.getCheque();
            if (chequeOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pago (" + pago + ") cannot be destroyed since the Cheque " + chequeOrphanCheck + " in its cheque field has a non-nullable pago field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Factura factura = pago.getFactura();
            if (factura != null) {
                factura.getPagoList().remove(pago);
                factura = em.merge(factura);
            }
            em.remove(pago);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Pago> findPagoEntities() {
        return findPagoEntities(true, -1, -1);
    }

    public List<Pago> findPagoEntities(int maxResults, int firstResult) {
        return findPagoEntities(false, maxResults, firstResult);
    }

    private List<Pago> findPagoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Pago.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Pago findPago(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Pago.class, id);
        } finally {
            em.close();
        }
    }

    public int getPagoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Pago> rt = cq.from(Pago.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
